package telex;
/*
 * IQFWriter.java
 *
 * Copyright (c) 2007-2008 Colin Bayer, Douglas Downey, Oren Etzioni,
 *   University of Washington Computer Science and Engineering
 * 
 * See the file "COPYING" in the root directory of this distribution for
 * full licensing information.
 */

import java.nio.charset.Charset;
import java.io.RandomAccessFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class IQFWriter {
	public IQFWriter(String aPath) throws FileNotFoundException, IOException {
		this(aPath, true);
	}
	
	public IQFWriter(String aPath, boolean aDelete, boolean append)
		throws FileNotFoundException, IOException {
			// delete any existing output file, to prevent weird hybrids of two output passes
			// from confusing the hell out of Colin at 9 in the morning.
			File f = new File(aPath);
		
			if (aDelete) {
				f.delete();
			}
			else if(append) {
				if(!f.exists())
					append = false;
			}
			
			mPath = aPath;		
			mFile = new RandomAccessFile(aPath, "rw");

			mQueryCount = 0;
			mIsFinalized = false;
			mUTF8 = Charset.forName("UTF-8");
			if(append) {
				mQueryCount = Integer.parseInt(mFile.readLine().split(" ")[1]);
				mFile.seek(mFile.length());
			}
			else
			  mFile.write("IQF !BAD-COUNT!\n".getBytes(mUTF8));
		}
	
	public IQFWriter(String aPath, boolean aDelete) throws FileNotFoundException, IOException {
		// delete any existing output file, to prevent weird hybrids of two output passes
		// from confusing the hell out of Colin at 9 in the morning.
		this(aPath, aDelete, false);
}
	
	public boolean writeQuery(Query q) throws IOException {
		if (mIsFinalized) return false;
		
		// sanity-check the query for emptiness.
		if (q.getQueryString().length() == 0) return false;
		
		//System.out.println(q);
		
		QueryString wds = q.getQueryString();
		
		mFile.write((wds.length() + "\t").getBytes(mUTF8));
		
		mFile.write((wds.getFlattened("\t") + "\t").getBytes(mUTF8));
		
		String ud = q.getUserDataString();
		
		mFile.write((q.getResult() + ((ud == null) ? "" : ("\t" + ud)) + "\n").getBytes(mUTF8));
		
		mQueryCount++;
		return true;
	}
	
	public boolean finish() throws IOException {
		if (mIsFinalized) return false;
		
		/* seek to the beginning and overwrite the header. */
		mFile.seek(0);
		
		//System.out.println("debug: mQueryCount is " + mQueryCount);
		
		mFile.write((String.format("IQF %1$-11d\n", mQueryCount)).getBytes(mUTF8));
		mFile.close();
		
		mIsFinalized = true;
		
		return true;
	}
	
	public String getPath() { return mPath; }
	public int getQueryCount() { return mQueryCount; }
	
	private RandomAccessFile mFile;
	private String mPath;
	
	private int mQueryCount;
	private boolean mIsFinalized;
	private Charset mUTF8;
	
	/* testing code. */
	public static void main(String[] aArgs) {
		if (aArgs.length < 1) {
			System.out.println("Usage: java IQFWriter [path to IQF file]");
			System.exit(255);
		}
		
		try {
			IQFWriter iqfw = new IQFWriter(aArgs[0]);
			
			iqfw.writeQuery(new Query(new String[]{"a"}, 12345, null));
			iqfw.writeQuery(new Query(new String[]{"a", "b", "c", "d", "e"}, 456, "foo;bar"));
			
			iqfw.finish();
		} catch (Exception e) {
			System.out.println(e);
			System.out.println("Writing of IQF file failed.");
		}
	}
}
